package com.boss.thirteen.service.impl;

import com.boss.salary.constant.SystemDictConstant;
import com.boss.salary.entity.SalaryPaymentRequisitionBack;
import com.boss.salary.service.IRedisService;
import com.boss.thirteen.dao.ISalaryThirteenMonthDao;
import com.boss.thirteen.dao.ISalaryThirteenMouldDao;
import com.boss.thirteen.dao.IThirteenAgencyVerifyDao;
import com.boss.thirteen.dao.IThirteenPaymentBackDao;
import com.boss.thirteen.entity.SalaryThirteenMonth;
import com.boss.thirteen.entity.ThirteenAgencyVerify;
import com.boss.thirteen.service.IThirteenSalaryEndAsyncService;
import com.singularsys.jep.JepException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@EnableAsync
public class ThirteenSalaryEndAsyncServiceImpl implements IThirteenSalaryEndAsyncService {
    /**
     * 引入日志框架常量
     */
    private static final Logger logger = LoggerFactory.getLogger(ThirteenSalaryEndAsyncServiceImpl.class);
    @Autowired
    private IRedisService redisService;
    @Autowired
    private ISalaryThirteenMonthDao salaryThirteenMonthDao;
    @Autowired
    private IThirteenAgencyVerifyDao thirteenAgencyVerifyDao;
    @Autowired
    private IThirteenPaymentBackDao thirteenPaymentBackDao;
    @Autowired
    private ISalaryThirteenMouldDao salaryThirteenMouldDao;
    /**
     * 缓解月结数据库超时问题通过循环分成小的事务
     * @param province
     * @param agencyIds
     * @param yearMap
     * @param agencyNameMap
     * @param agencyCodeMap
     * @throws ParseException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws JepException
     */
    @Async
    @Override
    public  void saveMonthEndAsynchronous( String province, List<String> agencyIds, Map<String, String> yearMap, Map<String, String> agencyNameMap, Map<String, String> agencyCodeMap,  String uuid) throws ParseException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, JepException {
        StringBuffer requestMessage=new StringBuffer();
        DecimalFormat df=new DecimalFormat("0.00");
        logger.info("=======十三月年结异步方法开始==============");
        List<ThirteenAgencyVerify> agencyVerifyList = thirteenAgencyVerifyDao.getAgencyVerifyByAgencyIds(null);
        for(int i=0;i<agencyIds.size();i++){
            saveMonthEnds(province,agencyIds.get(i),yearMap,agencyNameMap,agencyCodeMap,requestMessage);
            redisService.put(uuid,df.format((float)(i+1)/agencyIds.size()));
            System.out.println(df.format((float)(i+1)/agencyIds.size()));
            if(i+1==agencyIds.size()){
                redisService.del(province+"thirteenLunarKnot");
            }
        }
        if(StringUtils.isEmpty(requestMessage.toString())) {
            redisService.put(uuid, "S");
            if(agencyIds.size()==agencyVerifyList.size()){
                salaryThirteenMouldDao.updateSalaryThirteenMouldStatus(agencyVerifyList.get(0).getMouldKey(),SystemDictConstant.IS_END,null);
            }
        }else{
            redisService.put(uuid,"F-"+requestMessage.toString());
        }
        logger.info("=======十三月年结异步方法结束==============");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public  void saveMonthEnds(String province, String agencyId, Map<String, String> yearMap, Map<String, String> agencyNameMap, Map<String, String> agencyCodeMap,StringBuffer requestMessage) throws ParseException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, JepException {

        try{
            // 批量修改单位审核表的上报状态后，增加下个月的初始数据
            logger.info("==================批量修改审核表数据 Begin ================");
            List<String> agencyIds= new ArrayList<>();
            agencyIds.add(agencyId);
            thirteenAgencyVerifyDao.updateAgencyVerifyEndStatus(province,agencyIds,yearMap.get(agencyId), SystemDictConstant.IS_END);
            logger.info("==================批量修改审核表数据 End ================");

            logger.info("==================批量存储工资表历史表数据 Begin ================");
            // 转换工资表数据并添加到历史表
            Map<String, Object> params=new HashMap<>();
            params.put("agencyId",agencyId);
            params.put("province",province);
            List<SalaryThirteenMonth> stms=salaryThirteenMonthDao.selectSalaryThirteenMonth(params);
            List<String> ids=stms.stream().map(SalaryThirteenMonth::getId).collect(Collectors.toList());
            salaryThirteenMonthDao.deleteSalaryThirteenMonth(ids);
            salaryThirteenMonthDao.batchInsertSalaryThirteenHis(stms,yearMap.get(agencyId));
            logger.info("==================批量存储工资表历史表数据 End ================");

            logger.info("==================批量存储支付回盘数据 Begin ================");
            //支付回盘信息保存到历史表中，同时清空回盘信息
            List<SalaryPaymentRequisitionBack> spList=thirteenPaymentBackDao.getPayBackData(agencyId);
            thirteenPaymentBackDao.deletePayBackData(agencyId);
            thirteenPaymentBackDao.batchInsertPayBackHistoryData(spList,yearMap);
            logger.info("==================批量存储支付回盘数据 End ================");


        }catch (Exception e){
            logger.info("月结后续方法错误：",e);
            requestMessage.append(agencyNameMap.get(agencyId));
        }

    }
}
